<?php

/**

@todo: directly put basic features like the Mono- and PropertyFactory's way of creating the Phlame object 

*/

class ServiceImpl implements Service
{
    /**
     * @var AutoUpdater
     */
    private $_AutoUpdater;
    
    /**
     * @var Factory
     */
    private $_Factory;
    
    protected $_hold = array();
    
    public function __construct(AutoUpdater $AutoUpdater, Factory $Factory)
    {
        $this->_AutoUpdater = $AutoUpdater;
        $this->_Factory = $Factory;
    }
    
    public function __toString()
    {
        return sprintf("%s(%s)+%s", get_class($this), $this->getFactory(), $this->getAutoUpdater());
    }
    
    public function __destruct()
    {
        if (defined('DEBUG')) printf("\nDestroying %s#F:%s\n", get_class($this), get_class($this->_Factory));
        $this->_Factory = NULL;
        #MapperRegistry::cleanUp();
    }
    
    /**
     * @return Factory
     */
    public function getFactory()
    {
        return $this->_Factory;
    }
    
    /**
     * @return AutoUpdater
     */
    public function getAutoUpdater()
    {
        return $this->_AutoUpdater;
    }
    
    public function __call($func, $args)
    {
        $r = call_user_func_array(array($this->getAutoUpdater(), $func), $args);
        return $r instanceof Mapper ? $this : $r;
    }
    
    public function get(&$id = NULL)
    {
        if (empty($this->_hold)) {
            if (!$data = $this->getAutoUpdater()->get($id)) {
                return false;
            }
            $Phlame = $this->_create($data);
            if (!$Phlame) {
                $this->_hold = $data; # if creation failed, data will be hold
            }
        } else {
            $Phlame = $this->_create($this->_hold); # retry to use the data
            if ($Phlame) {
                $this->_hold = array(); # if it didn't fail, set to empty
            }
        }
        if ($Phlame instanceof Phlame) {
            MapperRegistry::register($Phlame);
            $id = $Phlame->getID();
        }
        return $Phlame;
    }
    
    public function getAll()
    {
        $ret = array();
        while ($o = $this->get($id)) {
        	$ret[$id] = $o;
        }
        return !empty($ret) ? $ret : false;
    }
    
    protected function _create(array $data)
    {
        return $this->getFactory()->create($data);
    }
    
    public function inform(array $data)
    {
        $this->getAutoUpdater()->inform($data);
    }
}